package com.lin.filegraph.utils.cluster;

import com.lin.filegraph.utils.compdg.ComponentEdge;
import com.lin.filegraph.utils.compdg.ComponentGraph;
import com.lin.filegraph.utils.compdg.ComponentNode;
import com.lin.filegraph.utils.name.DirSimilarity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @description:
 * @author: linhuaixu
 * @time: 2023/5/18 16:05
 */

public class NeighbourRank {

    public static void neighbourUnion(ComponentGraph graph) {
        System.out.println("*********聚合亲属节点******");
        int n = graph.getAllComponents().size();
        int[][] ranks = new int[n][n];
        for (ComponentEdge ce : graph.getAllComponentEdges()) {
            ComponentNode pre = ce.getPreComponent();
            ComponentNode post = ce.getPostComponent();
            int i = graph.getAllComponents().indexOf(pre);
            int j = graph.getAllComponents().indexOf(post);
            if(j<0||i<0)
                System.out.println(i+"-"+j+" "+pre.getStrComponentName()+"-"+post.getStrComponentName());
            ranks[i][j] = 1;
        }

        // 遍历
        List<List<ComponentNode>> listUnion = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int[] line1 = ranks[i];
            ComponentNode cn1 = graph.getAllComponents().get(i);
            boolean isOk=false;
            for(List<ComponentNode> list :listUnion){
                if(list.contains(cn1)){
                    isOk=true;
                    break;
                }
            }
            if(isOk)
                continue;
            //非独立节点
            if (graph.getNeighbours(cn1).size() > 0 && graph.getNeighbours(cn1) != null) {
                List<ComponentNode> lists = new ArrayList<>();
                for (int j = i + 1; j < n; j++) {
                    int[] line2 = ranks[j];
                    ComponentNode cn2 = graph.getAllComponents().get(j);
                    if (DirSimilarity.getSimLevelOfNode(cn1, cn2) > 0) {
                        boolean isSame = false;
                        boolean isSeparate=true;
                        // 对比行
//						if (!equalRank(line1, line2)) {
//							continue;
//						}
                        for (int k = 0; k < n&&k!=i&k!=j; k++) {
                            if (ranks[k][i] != ranks[k][j]) {
                                isSame = false;
                                break;
                            }
                            if(ranks[k][i]>0||ranks[k][j]>0)
                                isSeparate=false;
                        }

                        if(!isSame)
                            continue;

                        for (int k = 0; k < n&&k!=i&k!=j; k++) {
                            if (ranks[i][k] != ranks[j][k]) {
                                isSame = false;
                                break;
                            }
                            if(ranks[i][k]>0||ranks[j][k]>0)
                                isSeparate=false;
                        }
                        for(List<ComponentNode> list:listUnion)
                            if(list.contains(cn2))
                                isSeparate=true;
                        if (isSame&&cn2.isFeature()!=true) {//&&!isSeparate&&ClusterPreJudge.enableCluster(cn1, cn2, graph)
                            lists.add(cn2);
                        }
                    }
                }
                if (lists != null && lists.size() > 0&&cn1.isFeature()==false) {
                    lists.add(cn1);

                    listUnion.add(lists);
                }
            }
        }

        if (listUnion != null && listUnion.size() > 0) {
            for (List<ComponentNode> list : listUnion) {
                System.out.println("聚合list....");
                graph.mergeNodes(list);
            }
//			ComponentRules.executeRule2(graph);
        }
    }

    public static boolean equalRank(int[] a, int b[]) {
        if (a.length != b.length) {
            return false;
        } else {
            if (!Arrays.equals(a, b)) {
                return false;
            }
        }
        return true;
    }
}

